package org.dq.like.pojo;

import lombok.Data;

import java.time.LocalDate;

/**
 * @author klh
 * @date 2023/09/11 15:35:34
 */
@Data
public class LunarDate {

    private int year;
    private int month;
    private int day;
    private boolean leap;

    public LunarDate() {
    }

    // 构造函数
    public LunarDate(int year, int month, int day, boolean leap) {
        this.year = year;
        this.month = month;
        this.day = day;
        this.leap = leap;
    }

    // 将农历日期转换为公历日期
    public LocalDate toGregorianDate() {
        // 农历年份的起始公历年份
        int startYear = 1900;

        // 公历日期的起始值
        int gregorianYear = startYear;
        int gregorianMonth = 1;
        int gregorianDay = 31;

        // 计算农历日期和公历日期的差值
        int differenceInDays = calculateDifferenceInDays();

        // 根据差值计算公历日期
        gregorianYear = startYear;
        gregorianMonth = 1;
        gregorianDay = 31;

        while (differenceInDays > 0) {
            LocalDate currentDate = LocalDate.of(gregorianYear, gregorianMonth, gregorianDay);

            // 判断当前公历日期是否是闰年的二月，如果是则需要加一天
            if (currentDate.isLeapYear() && gregorianMonth == 2) {
                differenceInDays--;
            }

            // 减去一天，并更新公历日期
            differenceInDays--;
            gregorianDay--;

            // 如果公历日期为当月的第一天，需要更新月份和日期
            if (gregorianDay < 1) {
                gregorianMonth--;

                if (gregorianMonth < 1) {
                    gregorianYear--;
                    gregorianMonth = 12;
                }

                gregorianDay = getDaysInMonth(gregorianYear, gregorianMonth);
            }
        }

        return LocalDate.of(gregorianYear, gregorianMonth, gregorianDay);
    }

    // 计算农历日期和公历日期的差值
    private int calculateDifferenceInDays() {
        // 计算农历日期和公历日期的差值，假设使用一个数组来存储每个农历月的天数
        int[] lunarMonthDays = {0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30};
        int differenceInDays = 0;

        // 循环计算每个农历月的天数，加到差值中
        for (int i = 1; i <= this.month; i++) {
            differenceInDays += lunarMonthDays[i];
        }

        // 加上农历日期的天数
        differenceInDays += this.day;

        // 减去1900年到今年的天数
        for (int i = 1900; i < this.year; i++) {
            differenceInDays += LocalDate.of(i, 12, 31).isLeapYear() ? 366 : 365;
        }

        // 减去当前年的1月1日到今天的天数
        LocalDate currentDate = LocalDate.of(this.year, 1, 1);
        while (currentDate.getMonthValue() != this.month || currentDate.getDayOfMonth() != this.day) {
            differenceInDays--;
            currentDate = currentDate.plusDays(1);
        }

        return differenceInDays;
    }

    // 获取某一年某一月的天数
    private int getDaysInMonth(int year, int month) {
        switch (month) {
            case 2:
                return LocalDate.of(year, 2, 1).isLeapYear() ? 29 : 28; // 闰年2月有29天，否则有28天
            case 4:
            case 6:
            case 9:
            case 11:
                return 30; // 4、6、9、11月都是30天
            default:
                return 31; // 其他月份都是31天
        }
    }
}
